package com.cskaoyan.order.mq;

import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.order.constant.OrderRetCode;
import com.cskaoyan.order.constant.OrderConstants;
import com.cskaoyan.order.dal.entitys.Order;
import com.cskaoyan.order.dal.entitys.OrderItem;
import com.cskaoyan.order.dal.entitys.Stock;
import com.cskaoyan.order.dal.persistence.OrderItemMapper;
import com.cskaoyan.order.dal.persistence.OrderMapper;
import com.cskaoyan.order.dal.persistence.StockMapper;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.PostConstruct;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;

import static com.cskaoyan.order.constant.OrderConstants.*;

/**
 * @auther cskaoyan
 * @date 2022/5/23:17:56
 */
@Component
public class DelayOrderCancelConsumer {

    @Autowired
    OrderMapper orderMapper;


    @Autowired
    OrderItemMapper orderItemMapper;


    @Autowired
    StockMapper stockMapper;
    private DefaultMQPushConsumer consumer;

    @PostConstruct
    public void init() {
        consumer =
                new DefaultMQPushConsumer("delay_order_cancel_consumer");


        consumer.setNamesrvAddr("127.0.0.1:9876");

        consumer.setMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                // 在这里实现订单超时自动取消的逻辑
                // 1. 从message获取orderId
                // 2. 根据orderId, 查询订单的状态，如果订单的状态是已支付, 或者已取消，什么都不做
                // 3. 如果订单的状态初始化，那说明订单没有支付成功，执行订单自动取消
                //    a. 修改订单状态为已取消
                //    b. 根据OrderId，获取订单中的所有订单商品条目，根据每一个订单商品条目购买的数量
                //      -lockCount   +stockCount
                // 获取消息
                try {
                    MessageExt message = msgs.get(0);
//                    String startTimeStr = message.getUserProperty("startTimeStr");
//                    long endTime = System.currentTimeMillis();
//                    System.out.println("time span：" + (endTime - Long.parseLong(startTimeStr)));
                    byte[] body = message.getBody();
                    // 解析并消费
                    String orderId = new String(body, 0, body.length, "utf-8");
                    Order order1 = orderMapper.selectByPrimaryKey(orderId);
                   if(order1.getStatus().equals(ORDER_STATUS_PAYED)||order1.getStatus().equals(ORDER_STATUS_TRANSACTION_CANCEL)){   return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}
                    if(order1.getStatus().equals(ORDER_STATUS_INIT)){
                        Order order = new Order();
                        order.setOrderId(orderId);
                        order.setStatus(ORDER_STATUS_TRANSACTION_CANCEL);
                        order.setUpdateTime(new Date());
                        int effectRows = orderMapper.updateByPrimaryKeySelective(order);
                            if (effectRows < 1) {
                                throw new BizException(OrderRetCode.DB_SAVE_EXCEPTION.getCode(), OrderRetCode.DB_SAVE_EXCEPTION.getMessage());
                            }

                            // 获取订单中的itemId，需要通过这个id修改库存表
                            Example example = new Example(OrderItem.class);
                            example.createCriteria().andEqualTo("orderId", orderId);
                            List<OrderItem> orderItems = orderItemMapper.selectByExample(example);
                            for (OrderItem orderItem : orderItems) {
                                Long itemId = orderItem.getItemId();
                                Integer num = orderItem.getNum();
                                Stock stock = new Stock();
                                stock.setStockCount((long) -num);
                                stock.setLockCount(num);
                                stock.setItemId(itemId);
                                stockMapper.updateStock(stock);
                                // TODO: 也没管限购的问题
                                orderItem.setStatus(OrderConstants.ORDER_ITEM_STATUS_RELEASED);
//                int effectRows2 = orderItemMapper.updateByPrimaryKey(orderItem);
//                if (effectRows2 < 1) {
//                    throw new BizException(OrderRetCode.DB_SAVE_EXCEPTION.getCode(), OrderRetCode.DB_SAVE_EXCEPTION.getMessage());
//                }
                            }

                    }
                    System.out.println(message.getMsgId() + ":" + orderId);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                }catch (Exception e) {
                    return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });

        try {
            consumer.subscribe("delay_order_cancel", "*");
            consumer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
    }



}
